# -*- coding: utf-8 -*-
# !/usr/bin/env python
import copy
import os
import shutil
import subprocess
import xml.dom.minidom
import logging
from django.conf import settings
import requests

from components.resource_management.system_other_privilege.dao import sys_other_privilege_dict_in_url_pass
from utils.views import ReturnClass
logger = logging.getLogger('django')

class MvnClass():
    def exec_local_cmd(self, command, cwd):
        ret = subprocess.run(command, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding="gbk",
                             timeout=600,cwd=cwd)
        if ret.returncode == 0:
            logger.info("success: %s" %ret.stdout)
        else:
            logger.error("error: %s" %(ret.stdout + ret.stderr))
        self.exec_local_cmd_returncode = ret.returncode
        return (ret.stdout)

    def mvn_build(self, setting_xml_text, app_code_path, project_versions):
        self.project_versions = project_versions
        cmd = "git checkout ."
        cmd_re_data = self.exec_local_cmd(cmd, app_code_path)
        if self.exec_local_cmd_returncode:
            return ReturnClass.return_bust('构建失败，清理git环境失败：%s' % cmd_re_data)

        setting_xml_file = self.create_update_setting_xml_file(app_code_path, setting_xml_text)

        if ReturnClass.if_ok(self.project_versions_judge(project_versions)):
            now_snapshot_project_version = self.snapshot_project_versions_add(project_versions)
        else:
            return ReturnClass.return_bust("错误的版本输入")

        # if project_versions.find("SNAPSHOT") == -1:
        #     cmd = 'mvn --batch-mode -Dtag="{project_versions}"  -DreleaseVersion="{project_versions}" -DdevelopmentVersion="{now_snapshot_project_version}" release:prepare ' \
        #           '-f pom.xml -s {setting_xml} -Darguments="-Dmaven.javadoc.failOnError=false" release:perform'.format(
        #         setting_xml=setting_xml_file, now_snapshot_project_version=now_snapshot_project_version,
        #         project_versions=project_versions)
        # else:
        #     cmd = 'mvn clean versions:set -DnewVersion="{project_versions}"'.format(
        #         project_versions=project_versions)
        #     cmd_re_data = self.exec_local_cmd(cmd, app_code_path)
        #     if not self.exec_local_cmd_returncode:
        #         cmd = 'mvn clean deploy -s {setting_xml}'.format(
        #             setting_xml=setting_xml_file)
        cmd = 'mvn clean versions:set -DnewVersion="{project_versions}"'.format(
            project_versions=project_versions)
        cmd_re_data = self.exec_local_cmd(cmd, app_code_path)
        if not self.exec_local_cmd_returncode:
            cmd = 'mvn clean deploy -s {setting_xml}'.format(
                setting_xml=setting_xml_file)

        cmd_re_data += self.exec_local_cmd(cmd, app_code_path)
        if self.exec_local_cmd_returncode:
            return ReturnClass.return_bust('构建包或仓库推送失败：%s' %cmd_re_data)
        return ReturnClass.return_succeed('构建推送应用包成功')

    def create_update_setting_xml_file(self, app_code_path, text):
        setting_xml_file = os.path.join(app_code_path, 'setting.xml')
        hooks = open(setting_xml_file, 'w+')
        hooks.write(text)
        hooks.close()
        return setting_xml_file

    def project_versions_judge(self, project_versions):
        project_versions_list = project_versions.split('.')
        if not len(project_versions_list) == 3:
            return ReturnClass.return_bust('不合法的版本号')
        judge_count = 0
        for project_versions_list_one in project_versions_list:
            project_versions_list_one_judge = copy.deepcopy(project_versions_list_one)
            judge_count += 1
            if judge_count == 3:
                project_versions_list_one_judge = str(project_versions_list_one).replace("-SNAPSHOT", "")
            try:
                int(project_versions_list_one_judge)
            except:
                return ReturnClass.return_bust('不合法的版本号')
        return ReturnClass.return_succeed('合法的版本号')

    def snapshot_project_versions_add(self, project_versions):
        project_versions_list = project_versions.split(".")
        project_versions_nu = project_versions_list[2].replace("-SNAPSHOT", "")
        project_versions_list[2] = str(int(project_versions_nu) + 1) + "-SNAPSHOT"
        project_versions_end = ".".join(project_versions_list)
        return project_versions_end

    def analysis_pom_package_info(self, pom_path):
        pom_path_file = os.path.join(pom_path, "pom.xml")
        dom = xml.dom.minidom.parse(pom_path_file)
        root = dom.documentElement
        self.project_package_name = ""
        for childNodes_one in root.childNodes:
            if childNodes_one.nodeName != '#text':
                if childNodes_one.tagName == "artifactId":
                    self.artifactid = childNodes_one.firstChild.data
                    self.project_package_name += childNodes_one.firstChild.data
                if childNodes_one.tagName == "packaging":
                    self.project_package_name += ".%s" % childNodes_one.firstChild.data

        self.project_package_path = os.path.join(pom_path, "target", self.project_package_name)
        return True

    def copy_package_local_repository(self):
        package_local_repository_path = os.path.join(settings.APP_CONF['LocalRepository'], self.artifactid, self.project_versions)
        if not os.path.exists(package_local_repository_path):
            os.makedirs(package_local_repository_path)
        shutil.copy(self.project_package_path, package_local_repository_path)
        return os.path.join(package_local_repository_path, self.project_package_name)

    def get_local_repository_package_path(self, project_versions, artifactid):
        file_path = ""
        self.package_local_repository_path = os.path.join(settings.APP_CONF['LocalRepository'], artifactid, project_versions)
        for root, dirs, files in os.walk(self.package_local_repository_path):
            for file in files:
                file_path = os.path.join(root, file)
                break
            break
        return file_path

    def get_nexus_package_download_path(self,nexus_dict, soft_dict):
        package_format = ""
        if soft_dict['package_type_code'] == 'jar':
            package_format = "jar"
        elif soft_dict['package_type_code'] == 'vue':
            package_format = "zip"

        nexus_url = sys_other_privilege_dict_in_url_pass(nexus_dict['nexus_url'])

        nexus_url = nexus_url.format(nexus_user = nexus_dict['nexus_user'],
            nexus_pass = nexus_dict['nexus_pass'])

        nexus_soft_download_url = """{nexus_url}/repository/{nexus_repository}/{nexus_groupid}/{nexus_soft_artifact}/{nexus_soft_version}/{nexus_soft_artifact}-{nexus_soft_version}.{package_format}""".format(
            nexus_url = nexus_url,
            nexus_repository = nexus_dict['nexus_repository'],
            nexus_groupid=soft_dict['soft_groupid'].replace('.', '/'),
            nexus_soft_artifact=soft_dict['artifact'],
            nexus_soft_version=soft_dict['soft_version'],
            package_format=package_format
        )

        return nexus_soft_download_url

    def download_file(self, url, save_path=""):
        if save_path == "":
            save_path = url.split(os.path.sep)[-1]
        with requests.get(url, stream=True) as fget:
            if not fget.ok:
                return False
            file_size = int(fget.headers["Content-Length"])
            print('-' * 32)
            print(f"Name: {save_path}")
            print(f"Size: {file_size / (1000 ** 2)}Mb")
            print(f"Link: {url}")
            print('-' * 32)
            chunk_size = 512
            file_done = 0
            with open(save_path, "wb") as fw:
                for chunk in fget.iter_content(chunk_size):
                    fw.write(chunk)
                    file_done = file_done + chunk_size
                    percent = file_done / file_size
                    if file_done <= file_size:
                        print(f"Download: {percent:.2%}", end='\r')
                    else:
                        print("Download: 100%  ")

        return True